package com.sdy.hospitalguard.h5.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sdy.common.model.BizException;
import com.sdy.common.model.Response;
import com.sdy.common.utils.Assert;
import com.sdy.common.utils.IdCardUtil;
import com.sdy.hospitalguard.biz.constants.RedisConstants;
import com.sdy.hospitalguard.biz.dto.EscortAssociatedUserDTO;
import com.sdy.hospitalguard.biz.dto.PatientDTO;
import com.sdy.hospitalguard.biz.model.EscortAssociated;
import com.sdy.hospitalguard.biz.model.PatientInformation;
import com.sdy.hospitalguard.biz.service.EscortAssociatedService;
import com.sdy.hospitalguard.biz.service.HospitalUserService;
import com.sdy.hospitalguard.biz.service.PatientInformationService;
import com.sdy.hospitalguard.biz.service.SickbedService;
import com.sdy.hospitalguard.biz.utils.ParamChecker;
import com.sdy.hospitalguard.h5.vo.EscortAssociatedVo;
import com.sdy.mvc.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
 * <p>
 * 陪护
 * </p>
 *
 * @author fb
 * @since 2020/5/11
 */
@Slf4j
@RestController
@RequestMapping("/escort")
@Api(tags = "陪护相关接口")
public class EscortController extends BaseController{

    @Autowired
    private PatientInformationService patientInformationService;
    @Autowired
    private HospitalUserService hospitalUserService;
    @Autowired
    private EscortAssociatedService escortAssociatedService;
    @Autowired
    private RedisLockRegistry redisLockRegistry;
    @Autowired
    private SickbedService sickbedService;

    @PostMapping("/selectPatient")
    @ApiOperation(value = "住院号查询")
    public Response selectPatient(@RequestBody PatientDTO patientDTO) throws BizException {
        PatientInformation patientInformation = patientInformationService.selectPatient(patientDTO);
        if (patientInformation == null) {
            return Response.error("无此住院信息或已出院!");
        }
        Integer userId = patientInformation.getUserId();
        patientDTO.setName(hospitalUserService.getById(userId).getName());
        patientDTO.setPatientId(patientInformation.getId());
        return Response.success(patientDTO);
    }

    @PostMapping("/apply")
    @ApiOperation(value = "提交陪护申请")
    public Response apply(HttpServletRequest request, @RequestBody EscortAssociatedUserDTO escortAssociatedUserDTO) throws BizException, InterruptedException {
        Integer userId = getUserId(request);
        Integer patientId = escortAssociatedUserDTO.getPatientId();
        Assert.isNull(patientId, "患者登记id不能为空!");
        Assert.isTrue(!ParamChecker.checkParamRequired(escortAssociatedUserDTO.getName()), "参数<姓名>不能为空!");
        Assert.isTrue(!ParamChecker.checkParamRequired(escortAssociatedUserDTO.getIdCard()), "参数<身份证号>不能为空!");
        Assert.isTrue(!IdCardUtil.IDCardValidate(escortAssociatedUserDTO.getIdCard()).equals("true"), "身份证号格式错误!");
        Assert.isTrue(!ParamChecker.checkParamRequired(escortAssociatedUserDTO.getPhone()), "参数<手机号>不能为空!");
        Assert.isTrue(!escortAssociatedUserDTO.getPhone().matches(com.sdy.common.constant.Constants.REGEX_PHONE), "手机号格式错误!");
        if (patientInformationService.getById(patientId) == null) {
            return Response.error("无效的患者登记id!");
        }
        escortAssociatedUserDTO.setUserId(userId);
/*        Lock lockPatientId = redisLockRegistry.obtain(RedisConstants.LOCK_APPLY_ADDPATIENT_ESCORT + patientId);
        if(!lockPatientId.tryLock(10, TimeUnit.SECONDS)) {
            throw new BizException("向同个患者发起的陪护申请过于频繁，请规范操作!");
        }
        try {
            escortAssociatedService.saveEscortAssociated(escortAssociatedUserDTO);
        }finally {
            lockPatientId.unlock();
        }*/
        escortAssociatedService.saveEscortAssociated(escortAssociatedUserDTO);
        return Response.success("提交成功，待审核。");
    }

    @GetMapping("/selectEscortAssociatedPatient")
    @ApiOperation(value = "陪护的患者信息查询")
    public Response selectEscortAssociatedPatient(HttpServletRequest request, Page page) {
        Integer userId = getUserId(request);
        LambdaQueryWrapper<EscortAssociated> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(EscortAssociated::getUserId, userId);
        lambdaQueryWrapper.ne(EscortAssociated::getFlowState, 4);
        lambdaQueryWrapper.orderByAsc(EscortAssociated::getFlowState);
        lambdaQueryWrapper.orderByDesc(EscortAssociated::getCreateTime);
        IPage<EscortAssociated> escortAssociatedListIPage = escortAssociatedService.page(page, lambdaQueryWrapper);
        List<EscortAssociated> escortAssociatedList = escortAssociatedListIPage.getRecords();
        List<EscortAssociatedVo> escortAssociatedVoList = transform(escortAssociatedList);
        IPage<EscortAssociatedVo> result = new Page<EscortAssociatedVo>(page.getCurrent(), page.getSize(),
                escortAssociatedListIPage.getTotal()).setRecords(escortAssociatedVoList);
        return Response.success(result);
    }

/*    @GetMapping("/selectPatientChangeStatus")
    @ApiOperation(value = "查询能切换陪护状态的患者")
    public Response selectPatientChangeStatus(HttpServletRequest request) {
        Integer userId = getUserId(request);
        LambdaQueryWrapper<EscortAssociated> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(EscortAssociated::getUserId, userId);
        lambdaQueryWrapper.eq(EscortAssociated::getFlowState, 1);
        List<EscortAssociated> escortAssociatedList = escortAssociatedService.list(lambdaQueryWrapper);
        return Response.success(transform(escortAssociatedList));
    }*/

    @GetMapping("/selectPatientDetail")
    @ApiOperation(value = "陪护的患者详情信息,暂时不用")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "id", value = "陪护表id"),
    })
    public Response selectPatientDetail(Integer id) {
        return Response.success(patientInformationService.getById(escortAssociatedService.getById(id).getPatientId()));
    }

    @GetMapping("/cutoverPatient")
    @ApiOperation(value = "切换患者")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "id", value = "陪护表id"),
    })
    public Response cutoverPatient(HttpServletRequest request, Integer id) throws BizException, InterruptedException {
        Integer userId = getUserId(request);
        Integer code = 0;
        Lock lockPatientId = redisLockRegistry.obtain(RedisConstants.LOCK_APPLY_ADDPATIENT_ESCORT +
                escortAssociatedService.getById(id).getPatientId());
        if (!lockPatientId.tryLock(10, TimeUnit.SECONDS)) {
            throw new BizException("向同个患者发起的陪护申请过于频繁，请稍后重试!");
        }
        try {
            code = escortAssociatedService.cutoverPatient(userId, id);
        } finally {
            lockPatientId.unlock();
        }
        if (code == 1) {
            return Response.success("陪护关联已发起，待对方处理");
        } else {
            return Response.success("");
        }
    }

    @GetMapping("/cancelPatient")
    @ApiOperation(value = "解除患者")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "id", value = "陪护表id"),
    })
    public Response cancelPatient(HttpServletRequest request, Integer id) throws BizException {
        Integer userId = getUserId(request);
        escortAssociatedService.cancelPatient(userId, id);
        return Response.success("解除成功。");
    }

    private List<EscortAssociatedVo> transform(List<EscortAssociated> escortAssociatedList) {
        List<EscortAssociatedVo> escortAssociatedVoList = new ArrayList<>();
        for (int i = 0; i < escortAssociatedList.size(); i++) {
            EscortAssociatedVo escortAssociatedVo = new EscortAssociatedVo();
            if (escortAssociatedList.get(i).getStatus() == 1) {
                // 状态为出院
                escortAssociatedVo.setStatus(2);
            } else {
                escortAssociatedVo.setStatus(escortAssociatedList.get(i).getFlowState());
            }
            Integer patientId = escortAssociatedList.get(i).getPatientId();
            escortAssociatedVo.setId(escortAssociatedList.get(i).getId());
            escortAssociatedVo.setPatientId(patientId);
            escortAssociatedVo.setName(hospitalUserService.getById(patientInformationService.
                    getById(patientId).getUserId()).getName());
            escortAssociatedVo.setPhone(hospitalUserService.getById(patientInformationService.
                    getById(patientId).getUserId()).getPhone());
            escortAssociatedVo.setAdmissionNumber(patientInformationService.
                    getById(patientId).getAdmissionNumber());
            String bedNumber = sickbedService.getById(patientInformationService.getById(patientId).getSickbedId()).getSickbedNumber();
            escortAssociatedVo.setBedNumber(bedNumber);
            escortAssociatedVoList.add(escortAssociatedVo);
        }
        return escortAssociatedVoList;
    }

}
